﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinCourseControls.UControls
{
    /// <summary>
    /// Label-扩展控件
    /// </summary>
    public partial class LabelEx : Label
    {
        public LabelEx()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);  // 忽略窗口消息减少闪烁
            this.SetStyle(ControlStyles.UserPaint, true); // 设置不是由操作系统来绘制控件自身
            this.SetStyle(ControlStyles.DoubleBuffer, true); // 设置在缓冲区绘制，完成后再显示到页面-双缓冲可以防止因重绘控件而引起的闪烁。
            this.SetStyle(ControlStyles.ResizeRedraw, true);  // 调整大小时重绘控件
            this.SetStyle(ControlStyles.Selectable, true); // 设置控件可以接受焦点
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); // 支持控件设置透明色
            this.Size = new Size(80, 30); // 设置控件初始大小

        }

        private Color bColor = Color.Gray;
        /// <summary>
        /// 边框颜色
        /// </summary>
        public Color BColor
        {
            get { return bColor; }
            set { bColor = value;
                Refresh(); // 强制工作区无效，并且立即重绘
            }
        }

        private Color bgColor = Color.White; // 设置默认颜色
        /// <summary>
        /// 背景色
        /// </summary>
        public Color BgColor
        {
            get { return bgColor; }
            set
            {
                bgColor = value;
                Refresh();  // 强制工作区无效，并且立即重绘
            }
        }

        private int borderWidth=2;
        /// <summary>
        /// 边框粗细
        /// </summary>
        public int BorderWidth
        {
            get { return borderWidth; }
            set { borderWidth = value;
                Refresh();  // 强制工作区无效，并且立即重绘
            }
        }

        private int radius =5;
        /// <summary>
        /// 圆角度
        /// </summary>
        public int Radius
        {
            get { return radius; }
            set
            {
                radius = value;
                Refresh();
            }
        }

        private Color _oldBColor;
        private Color _oldBgColor;
        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseHover(e);
            _oldBColor = BColor;
            _oldBgColor = BgColor;
            BgColor = Color.Red;
            BColor = Color.Orange;
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            BgColor = _oldBgColor;
            BColor = _oldBColor;
        }
        /// <summary>
        /// 外观-重绘外观方法-用于当调用Refresh()方法时-触发这个事件来进行外观重绘。
        /// 这里如果重绘的话-就要把所有效果都重绘了，不要一部分重绘一部分用原来的-那样回很丑
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e); // 调用父类的绘画方法
            Graphics g = e.Graphics;  // 创建绘图对象
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; // 设置呈现质量
            g.Clear(this.Parent.BackColor); // 清空原有背景-以父容器的背景色进行填充-这样在重绘控件时相当于透明色

            Rectangle rect = new Rectangle(); // 边框区域实例
            if(BorderWidth>0) // 边框粗细判断
            {  // 设置边框粗细 
                rect.X = BorderWidth-1; // 边框粗细 - 1
                rect.Y = BorderWidth-1; // 边框粗细 - 1
                rect.Width = this.ClientRectangle.Width - BorderWidth * 2+ 1; // 工作区域宽度 - 边框粗细*2+1
                rect.Height = this.ClientRectangle.Height - BorderWidth * 2 + 1; // 工作区域高度 - 边框粗细*2+1
            }
            else // 没有设置边框粗细
            {
                rect.X =0;
                rect.Y = 0;
                rect.Width = this.ClientRectangle.Width;
                rect.Height = this.ClientRectangle.Height;
            }
            GraphicsPath rectRound = GetRoundedRect(rect, Radius); // 返回圆角矩形方法
            g.FillPath(new SolidBrush(BgColor), rectRound);//填充背景
            if(BorderWidth>0)
                g.DrawPath(new Pen(BColor, BorderWidth), rectRound);// 画边框 - 这里就把圆角矩形画出来了
            //文字对齐方式
            StringFormat f = new StringFormat();
            f.Alignment = StringAlignment.Center; // 设置文本水平对齐
            f.LineAlignment = StringAlignment.Center; // 设置文本垂直对齐
            g.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), rect, f);

        }

        /// <summary>
        /// 返回圆角矩形路径 
        /// </summary>
        /// <param name="rect">边框矩形</param>
        /// <param name="radius">圆角度</param>
        /// <returns>根据圆角度计算-返回一个圆角矩形</returns>
        private GraphicsPath GetRoundedRect(Rectangle rect, int radius)
        {  // 根据圆角度计算-返回一个圆角矩形
            GraphicsPath gp = new GraphicsPath();
            int x = rect.X;
            int y = rect.Y;
            int width = rect.Width;
            int height = rect.Height;

            //上
            gp.AddLine(new PointF(x + radius, y), new PointF(x + width - radius, y));
            //右上角
            gp.AddArc(new Rectangle(x + width - radius * 2, y, radius * 2, radius * 2), 270F, 90F);
            //右
            gp.AddLine(new PointF(x + width, y + radius), new PointF(x + width, y + height - radius));
            //右下角
            gp.AddArc(new Rectangle(x + width - radius * 2, y + height - radius * 2, radius * 2, radius * 2), 0F, 90F);
            //下
            gp.AddLine(new PointF(x + radius, y + height), new PointF(x + width - radius, y + height));
            //左下角
            gp.AddArc(new Rectangle(x, y + height - radius * 2, radius * 2, radius * 2), 90F, 90F);
            //左
            gp.AddLine(new PointF(x, y + radius), new PointF(x, y + height - radius));
            //左上角
            gp.AddArc(new Rectangle(x, y, radius * 2, radius * 2), 180F, 90F);
            return gp;
        }
    }
}
